#include "AirkissCloud.h"
#include <netdb.h>


#define DEFAULT_LAN_PORT    12476

AirkissCloud AirkissCloud::mInstance;
static char pData[200]={0};
static unsigned short nLen = sizeof(pData);

static const airkiss_config_t akconf =
{
	(airkiss_memset_fn)&memset,
	(airkiss_memcpy_fn)&memcpy,
	(airkiss_memcmp_fn)&memcmp,
	0
};

AirkissCloud & AirkissCloud::Instance()
{
	return mInstance;
}

AirkissCloud::AirkissCloud()
	:thAirkissCloud(osPriorityNormal)
	,bIsInit(false)
{
	thAirkissCloud.start(this,&AirkissCloud::Bind);
}

AirkissCloud::~AirkissCloud()
{

}

void AirkissCloud::SetStack(NetworkInterface * _pNetWork)
{
	if(!bIsInit)return;
	pNetWork = _pNetWork;
}

void AirkissCloud::Init()
{
	pProfile = (TulingProfile *)(TulingConfig::Instance().GetProfile());	
	memset(strDeviceType,0,sizeof(strDeviceType));
	memset(strDeviceId,0,sizeof(strDeviceId));	
	sprintf(strDeviceType,"%s",pProfile->MC_mqttcfg.strDeviceType);
	sprintf(strDeviceId, "%s_%s", pProfile->AC_wificfg.strApiKey, pProfile->AC_wificfg.strDeviceID);
	TULING_LOGD("%s\n",strDeviceType);
	TULING_LOGD("%s\n",strDeviceId);	
	bIsInit = true;
}

void AirkissCloud::Start()
{
	if(!bIsInit)return;
	thAirkissCloud.signal_set(0x01);
}

void AirkissCloud::Bind()
{	
	while(1)
	{
		thAirkissCloud.signal_wait(0x01);		
		struct sockaddr_in sServer;
		sServer.sin_family = AF_INET;
		sServer.sin_port = htons(DEFAULT_LAN_PORT);
		sServer.sin_addr.s_addr = INADDR_ANY;
		int nServerAddrLen = sizeof(sServer);
		int nSockFd = -1;
		nSockFd = socket(AF_INET, SOCK_DGRAM, 0);
		bind(nSockFd, (struct sockaddr *)&sServer,sizeof(sServer));
		struct sockaddr_in sClient;
		int nClientAddrLen = sizeof(sClient);	
		setsockopt(nSockFd, SOL_SOCKET, SO_BROADCAST, &sServer, sizeof(sServer));
		int nRecvLen = -1;
		TULING_LOGI("Entry AirkissCloud");	
		TULING_LOGI("thread: id = %x, used = %d, max = %d", thAirkissCloud.gettid(), thAirkissCloud.used_stack(),thAirkissCloud.max_stack());
		
		while(1)
		{
			nRecvLen = recvfrom(nSockFd, pData, nLen, 0, (struct sockaddr*)&sClient, (socklen_t *)&nClientAddrLen);
			if(nRecvLen <= 0)
			{
				TULING_LOGE("Recv %d\n",nRecvLen);
				close(nSockFd);
				nSockFd = -1;
				break;
			}			
			airkiss_lan_ret_t ret = (airkiss_lan_ret_t)airkiss_lan_recv(pData, nLen, &akconf);
			airkiss_lan_ret_t packret;
			int nSendLen = 0;
			
			TULING_LOGD("ret = %d",ret);
			
			switch (ret)
			{
				case AIRKISS_LAN_SSDP_REQ:
					nLen = sizeof(pData);
					packret = (airkiss_lan_ret_t)airkiss_lan_pack(AIRKISS_LAN_SSDP_RESP_CMD, (void *)strDeviceType, (void *)strDeviceId, 0, 0, pData, &nLen, &akconf);
					if (packret != AIRKISS_LAN_PAKE_READY) 
					{
						TULING_LOGE("Pack lan packet error!\n");
						break;
					}
					TULING_LOGD("packret = %d",packret);
					
					nSendLen = sendto(nSockFd, pData, nLen,0,(struct sockaddr *)&sClient,nClientAddrLen);
					TULING_LOGD("nSendLen = %d",nSendLen);
					
					break;				
				default:
					TULING_LOGV("Pack is not ssdq req!\n");
				break;
			}
		}
		TULING_LOGI("Leave AirkissCloud\n");	
	}
}

